
import aima.search.framework.Successor;
import aima.search.framework.SuccessorFunction;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author genis
 */
public class CarsSuccessorFunctionSA implements SuccessorFunction {

    public List getSuccessors(Object state) {
        ArrayList retval = new ArrayList();

        State CarsState = (State) state;

        int Ndrivers = CarsState.getNDrivers();
        Random myRandom = new Random(System.nanoTime());

        if (Ndrivers >= 1) {
            int driMove = myRandom.nextInt(Ndrivers - 1);
            int drjMove;
            do {
                drjMove = myRandom.nextInt(Ndrivers - 1);
            } while(driMove == drjMove);
            int [] travsMove = CarsState.getDriver(driMove).getIdTravellers();
            if (travsMove.length > 1) {
                int tri = myRandom.nextInt(travsMove.length -1);
                State StateMove = new State(CarsState);
                StateMove.move(StateMove.getDriver(driMove),
                               StateMove.getDriver(drjMove), travsMove[tri]);
                retval.add(new Successor(State.MOVE, StateMove));
            }

            int driSwap = myRandom.nextInt(Ndrivers - 1);
            int [] travsSwap = CarsState.getDriver(driSwap).getIdTravellers();
            if (travsSwap.length > 1) {
                int triSwap = myRandom.nextInt(travsSwap.length - 1);
                State StateSwapStr = new State(CarsState);
                State StateSwapEnd = new State(CarsState);
                StateSwapStr.swapTravellers(StateSwapStr.getDriver(driSwap),
                        travsSwap[triSwap], true);
                StateSwapEnd.swapTravellers(StateSwapEnd.getDriver(driSwap),
                        travsSwap[triSwap], false);
                retval.add(new Successor(State.SWAP, StateSwapStr));
                retval.add(new Successor(State.SWAP, StateSwapEnd));
            }

            int[] avaliableDrivers = CarsState.getAvaliableDrivers();
            //int dri2 = myRandom.nextInt(Ndrivers - 1);
            if (avaliableDrivers.length > 1){
                int dri2 = myRandom.nextInt(avaliableDrivers.length-1);
                State StateAdd = new State(CarsState);
                if (StateAdd.addDriver(avaliableDrivers[dri2])) {
                    retval.add(new Successor(State.ADD, StateAdd));
                }
            }
            /*int driverSwap = myRandom.nextInt(Ndrivers - 1);
            Driver d = CarsState.getDriver(driverSwap);
            int[] travellers = d.getIdTravellers();
            if (travellers.length > 2) {
                int aux = myRandom.nextInt(travellers.length - 1);
                int aux2;
                do {
                    aux2 = myRandom.nextInt(travellers.length - 1);
                } while (aux == aux2);
                State StateSwap = new State(CarsState);
                StateSwap.swapInCar(d, travellers[aux], travellers[aux2]);
                retval.add(new Successor(State.SWAPCAR, StateSwap));
            }*/
        }
        if (Ndrivers >= 2) {
            int driDel = myRandom.nextInt(Ndrivers - 1);
            int drjDel;
            do {
                drjDel = myRandom.nextInt(Ndrivers - 1);
            } while(driDel == drjDel);
            State StateDel = new State(CarsState);
            if (StateDel.deleteDriver(driDel, drjDel)) {
                retval.add(new Successor(State.DELETE, StateDel));
            }
            /*if (StateDel.deleteDriverWithTravellers(driDel, drjDel)) {
                retval.add(new Successor(State.DELETE2, StateDel));
            }*/
        }

        return retval;
    }
}
